#ifndef XENENGINE_XEN_PHYSICAL_SPACE_HPP
#define XENENGINE_XEN_PHYSICAL_SPACE_HPP

#include "pch.hpp"
#include "xen/pch.hpp"
#include "xen/core.hpp"

namespace Xen::Physical {

class SphereGeomentry;
class BoxGeomentry;
class PlaneGeomentry;
struct PlaneParams;

using NearCollideCB = void(*)(void*, dGeomID, dGeomID);

class Space final {
public:
    friend class SphereGeomentry;
    friend class BoxGeomentry;
    friend class PlaneGeomentry;

    Space();
    ~Space();

    Ref<SphereGeomentry> CreateShpere(float r);
    Ref<BoxGeomentry> CreateBox(const glm::vec3& l);
    Ref<PlaneGeomentry> CreatePlane(const PlaneParams& params);

    inline void SetNearCollideCB(NearCollideCB& cb) {
        XEN_CORE_ASSERT(cb, "Near Collide Callback function is nullptr");
        cb_ = cb;
    }

    bool operator==(const Space& s) const { return IsSameAs(s); }
    bool operator!=(const Space& s) const { return !IsSameAs(s); }
    inline bool IsSameAs(const Space& s) const { return id_ == s.id_; }

    void Update(NearCollideCB cb, void* data);

private:
    dSpaceID id_;
    NearCollideCB cb_ = nullptr;

    static void defaultCollideCB(void*, dGeomID, dGeomID) {}
};

}

#endif
